package com.android.panballgame;

import java.util.Timer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.annotation.SuppressLint;
import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;

public class PBGameRenderer2 implements Renderer{

	//실제 도형
	Context context;	
	private PBBackground background;
	private PBVector [] vec; //코인 위치 좌표
	private PBVector clockVec; //아이템 위치 좌표
	private PBCoin [] coin; 
	private PBClock clock;	//시간 줄여주는 아이템
	private PBBall ball;	
	
	//경계 도형
	private PBCircle CirBall; //공
	private PBCircle[] CirCoin; //코인
	private PBCircle CirHole; //골인 구멍	
	private PBRectangle [] rec; //벽(장애물)
	
	private PBCircle CirHole2; //순간 이동 구멍
	private PBCircle CirClock; //아이템
		
	//가속도 계산 변수
	int oriX, oriY= 0;
	float sx, sy, vx, vy = 0;	
	
	//조건 변수
	boolean drawball; //공 골인 유무
	boolean inhole; //임의의 위치로 이동되는 구멍에 들어갔는가
		
	// 생성자
	@SuppressLint("NewApi")
	public PBGameRenderer2(Context context){
		
		if(PBEngine.useDb == 0){
			PBEngine.ballx = 0.2f;
			PBEngine.bally = 6.76f;
		}
		
		this.context = context;
		//각 도형 생성
		background = new PBBackground();
		coin = new PBCoin[7];
		vec = new PBVector[7];
		ball = new PBBall();
		clock = new PBClock();
		clockVec = new PBVector();
		
		for(int i = 0; i < 7; i++)
			coin[i] = new PBCoin();
		
		int ran1;
		if(PBEngine.useDb == 1)
			ran1 = PBEngine.coinLoc;
		else{
			ran1 = 1 + (int)(Math.random() * 5);
			PBEngine.coinLoc = ran1;
		}
		switch(ran1){
			case 1 :
				vec[0] = new PBVector(10.0f, 6.7f);
				vec[1] = new PBVector(4.45f, 5.55f);
				vec[2] = new PBVector(0.6f, 2.7f);
				vec[3] = new PBVector(10.1f, 2.9f);
				vec[4] = new PBVector(4.25f, 1.55f);
				vec[5] = new PBVector(10.05f, 0.25f);
				vec[6] = new PBVector(0.3f, 4.3f);
				break;
			case 2 :
				vec[0] = new PBVector(0.3f, 5.4f);
				vec[1] = new PBVector(3.0f, 4.2f);
				vec[2] = new PBVector(6.0f, 0.3f);
				vec[3] = new PBVector(7.0f, 2.8f);
				vec[4] = new PBVector(7.2f, 6.7f);
				vec[5] = new PBVector(10.1f, 2.9f);
				vec[6] = new PBVector(11.6f, 0.3f);
				break;
			case 3 :
				vec[0] = new PBVector(4.4f, 5.5f);
				vec[1] = new PBVector(10.0f, 5.5f);
				vec[2] = new PBVector(12.8f, 5.5f);
				vec[3] = new PBVector(7.0f, 2.8f);
				vec[4] = new PBVector(7.2f, 6.7f);
				vec[5] = new PBVector(10.1f, 2.9f);
				vec[6] = new PBVector(11.6f, 0.3f);
				break;
			case 4 :
				vec[0] = new PBVector(4.4f, 5.5f);
				vec[1] = new PBVector(10.0f, 5.5f);
				vec[2] = new PBVector(12.8f, 5.5f);
				vec[3] = new PBVector(10.1f, 2.9f);
				vec[4] = new PBVector(2.3f, 1.6f);
				vec[5] = new PBVector(5.8f, 1.6f);
				vec[6] = new PBVector(12.4f, 1.6f);
				break;
			case 5 :
				vec[0] = new PBVector(8.7f, 6.7f);
				vec[1] = new PBVector(0.5f, 4.15f);
				vec[2] = new PBVector(4.3f, 2.9f);
				vec[3] = new PBVector(11.4f, 2.9f);
				vec[4] = new PBVector(12.8f, 1.6f);
				vec[5] = new PBVector(4.3f, 0.3f);
				vec[6] = new PBVector(9.9f, 0.3f);
				break;
		}
		
		int ran2;
		if(PBEngine.useDb == 1)
			ran2 = PBEngine.itemLoc;
		else{
			ran2 = 1 + (int)(Math.random() * 3);
			PBEngine.itemLoc = ran2;
		}
		switch(ran2){
			case 1 :
				clockVec = new PBVector(11.5f, 6.65f);
				break;
			case 2 :
				clockVec = new PBVector(2.1f, 0.3f);
				break;
			case 3 :
				clockVec = new PBVector(7.25f, 4.25f);
				break;
		}
		
		//경계 도형 생성
		CirBall = new PBCircle((PBEngine.ballx + 0.475f), (PBEngine.bally + 0.475f), 0.475f); //공
		CirCoin = new PBCircle[7]; //코인
		for(int i = 0; i < 7; i++){
			CirCoin[i] = new PBCircle((vec[i].x + 0.475f), (vec[i].y + 0.475f), 0.475f);
		}		
		CirHole = new PBCircle(13.385f, 0.845f, 0.475f); //골인 구멍  
		CirHole2 = new PBCircle(7.725f, 2.125f, 0.475f); //순간이동 구멍
		CirClock = new PBCircle((clockVec.x + 0.475f), (clockVec.y + 0.475f), 0.475f);//아이템 시계

		
		rec = new PBRectangle[19];		
		//사각형들
		//X축과 나란한 벽
		rec[0] = new  PBRectangle(0f, 6.61f, 2.89f, 0.11f);		
		rec[1] = new  PBRectangle(2.07f, 5.3f, 3.6f, 0.11f);
		rec[2] = new  PBRectangle(9.8f, 5.3f, 1.53f, 0.11f);		
		rec[3] = new  PBRectangle(0f, 3.98f, 5.67f, 0.11f);		
		rec[4] = new  PBRectangle(6.96f, 3.98f, 4.37f, 0.11f);		
		rec[5] = new  PBRectangle(4.16f, 2.66f, 2.91f, 0.11f);
		rec[6] = new  PBRectangle(9.8f, 2.66f, 2.95f, 0.11f);		
		rec[7] = new  PBRectangle(2.07f, 1.35f, 2.2f, 0.11f);
		rec[8] = new  PBRectangle(6.96f, 1.35f, 4.37f, 0.11f);
		
		//Y축과 나란한 벽
		rec[9] = new  PBRectangle(2.07f, 1.35f, 0.11f, 2.74f);		
		rec[10] = new  PBRectangle(4.16f, 5.3f, 0.11f, 2.74f);		
		rec[11] = new  PBRectangle(5.56f, 5.3f, 0.11f, 1.42f);		
		rec[12] = new  PBRectangle(6.96f, 1.35f, 0.11f, 1.42f);
		rec[13] = new  PBRectangle(6.96f, 3.98f, 0.11f, 2.74f);		
		rec[14] = new  PBRectangle(8.38f, 3.98f, 0.11f, 4.26f);		
		rec[15] = new  PBRectangle(9.8f, 2.66f, 0.11f, 1.43f);		
		rec[16] = new  PBRectangle(11.22f, 0f, 0.11f, 1.46f);
		rec[17] = new  PBRectangle(11.22f, 5.3f, 0.11f, 2.74f);		
		rec[18] = new  PBRectangle(12.64f, 2.66f, 0.11f, 2.75f);
		
		//조건변수 초기화
		drawball = true;		
		inhole = false;
		if(PBEngine.useDb != 1)
			PBEngine.item1 = 1;
		
		if(PBEngine.useDb != 1){
			for(int i = 0; i < 7; i++)
				PBEngine.drawcoin[i] = 1;
		}		
	}
	
		@SuppressLint("NewApi")
		@Override
		public void onDrawFrame(GL10 gl) {
			try{
				Thread.sleep(PBEngine.GAME_THREAD_FPS_SLEEP);
			}catch (InterruptedException e){
				e.printStackTrace();
			}		
			gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);			
			gl.glEnable(GL10.GL_BLEND);
			gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
			
			for(int i = 0; i < 7; i++){//코인이 먹힌 경우
				if(PBOverlapTester.overlapCircles(CirBall, CirCoin[i]))			
					if(PBEngine.drawcoin[i] == 1){
						PBEngine.drawcoin[i] = 0;
						PBGame.sound(1);
						PBEngine.remain--;
						}
			}			

			if(PBOverlapTester.overlapCircles(CirBall, CirClock))//시계 아이템			
				if(PBEngine.item1 == 1){
					PBEngine.item1 = 0;
					PBGame.sound(3);
					PBEngine.MINUS_TIME = true;
				}
			
			if(PBOverlapTester.pointInCircle(CirHole2, CirBall.center)){//순간 이동 구멍
				inhole = true;
				PBGame.sound(2);
			}
			
			if(PBOverlapTester.pointInCircle(CirHole, CirBall.center))//공이 골인 지점에 들어간 경우
				if(drawball){
					if(PBEngine.remain <= 0){ //남은 과제 수가 0이면
						PBGame.sound(2);
						drawball = false;
						Timer timer = new Timer();
						timer.schedule(new PBDelay(), 1000);
						PBEngine.STATUS = PBEngine.CLEAR;
						PBEngine.WAIT = true;
					}else{
						PBEngine.HOLE = true;
					}
				}
			
			background(gl);
			coin(gl);
			if(PBEngine.item1 == 1)
				clock(gl);			
			if(drawball)	
				ball(gl);

		}
		

		//벽(장애물)에 부딪혔을 때
		private boolean obstacleS(){//남쪽
			boolean crash = false;			
			for(int i = 0; i < 19; i++){				
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 1){
					if( Math.abs(CirBall.center.y - rec[i].lowerLeft.y) >= Math.abs(CirBall.center.x - rec[i].lowerLeft.x))
						PBEngine.bally = rec[i].lowerLeft.y - CirBall.radius - CirBall.radius;
					else
						crash = true;
				}			
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 2){
					PBEngine.ballx = rec[i].lowerLeft.x - CirBall.radius - CirBall.radius;
					crash = true;
				}
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 3){
					if( Math.abs(CirBall.center.y - (rec[i].lowerLeft.y + rec[i].height)) >= Math.abs(CirBall.center.x - rec[i].lowerLeft.x))
						PBEngine.bally =  rec[i].lowerLeft.y + rec[i].height; 
					else
						crash = true;
				}				
			}			
			return crash;
		}
		
		private boolean obstacleN(){//북쪽
			boolean crash = false;			
			for(int i = 0; i < 19; i++){			
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 7){
					if( Math.abs(CirBall.center.y - rec[i].lowerLeft.y) >= Math.abs(CirBall.center.x - (rec[i].lowerLeft.x + rec[i].width)))
						PBEngine.bally = rec[i].lowerLeft.y - CirBall.radius - CirBall.radius;
					else
						crash = true;
				}			
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 8){
					PBEngine.ballx = rec[i].lowerLeft.x + rec[i].width;
					crash = true;
				}
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 9){
					if( Math.abs(CirBall.center.y - (rec[i].lowerLeft.y + rec[i].height)) >= Math.abs(CirBall.center.x - (rec[i].lowerLeft.x + rec[i].width)))
						PBEngine.bally =  rec[i].lowerLeft.y + rec[i].height; 
					else
						crash = true;
				}			
			}			
			return crash;			
		}
		
		private boolean obstacleE(){//동쪽
			boolean crash = false;			
			for(int i = 0; i < 19; i++){
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 1){
					if( Math.abs(CirBall.center.y - rec[i].lowerLeft.y) < Math.abs(CirBall.center.x - rec[i].lowerLeft.x))
						PBEngine.ballx = rec[i].lowerLeft.x - CirBall.radius - CirBall.radius;
					else
						crash = true;
				}
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 4){
					PBEngine.bally = rec[i].lowerLeft.y - CirBall.radius - CirBall.radius;
					crash = true;
				}			
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 7){
					if( Math.abs(CirBall.center.y - rec[i].lowerLeft.y) < Math.abs(CirBall.center.x - (rec[i].lowerLeft.x + rec[i].width)))
						PBEngine.ballx = rec[i].lowerLeft.x + rec[i].width;
					else
						crash = true;
				}				
			}			
			return crash;			
		}
		
		private boolean obstacleW(){//서쪽
			boolean crash = false;			
			for(int i = 0; i < 19; i++){			
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 3){ 
					if( Math.abs(CirBall.center.y - (rec[i].lowerLeft.y + rec[i].height)) < Math.abs(CirBall.center.x - rec[i].lowerLeft.x))
						PBEngine.ballx = rec[i].lowerLeft.x - CirBall.radius - CirBall.radius;
					else
						crash = true;
				}
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 6){ 
					PBEngine.bally =  rec[i].lowerLeft.y + rec[i].height; 
					crash = true;
				}
				if(PBOverlapTester.overlapCircleRectangle(CirBall, rec[i]) == 9){ 
					if( Math.abs(CirBall.center.y - (rec[i].lowerLeft.y + rec[i].height)) < Math.abs(CirBall.center.x - (rec[i].lowerLeft.x + rec[i].width)))
						PBEngine.ballx = rec[i].lowerLeft.x + rec[i].width;
					else
						crash = true;
				}			
			}			
			return crash;			
		}
		
		
		//가속도 이용해서 공의 속도 계산 및 적용
		private void acc(){
			//s= v0t + 1/2at², v = v0 + at 
			//기울임에 따라 공 이동
			
			// y 좌표 조정
			if(-9.8<=PBGame.accX && PBGame.accX<-0.1 && oriY != 2){
				if(PBEngine.bally > 6.96f){ //판 오른쪽 테두리
					PBEngine.bally = 6.96f;
					sy = 0;
					vy = 0;
				}
				else{					
					if(obstacleE()){ //장애물에 부딪혔을 때 obstacle 함수를 불러 처리함.
						sy = 0;
						vy = 0;
					}else{
						sy = vy + (0.5f)*PBGame.accX*(0.016f)*(0.015f);
						vy = vy + PBGame.accX*(0.016f)*(0.015f);
						PBEngine.bally = PBEngine.bally - sy; 
					}					
				}
				oriY = 1;				
			}else	if(-9.8<=PBGame.accX && PBGame.accX<-0.1 && oriY ==2 ){
				sy = 0;
				vy = 0;
				oriY = 1;
			}else if(0.1<PBGame.accX && PBGame.accX<=9.8 && oriY != 1){				
				if(PBEngine.bally < 0.1f){ //왼쪽 테두리
					PBEngine.bally = 0.1f;
					sy = 0;
					vy = 0;
				}
				else{
					if(obstacleW()){
						sy = 0;
						vy = 0;
					}else{
						sy = vy + (0.5f)*PBGame.accX*(0.016f)*(0.015f);
						vy = vy + PBGame.accX*(0.016f)*(0.015f);
						PBEngine.bally = PBEngine.bally - sy;						
					}
				}
				oriY = 2;	
			}else if(0.1<PBGame.accX && PBGame.accX<=9.8 && oriY == 1){
				sy = 0;
				vy = 0;
				oriY = 2;
			}else{
				sy = 0;
				vy = 0;
				oriY = 0;
			}			
			
			// x 좌표 조정	
			if(-9.8<=PBGame.accY && PBGame.accY<-0.1 && oriX != 2 ){
				if(PBEngine.ballx < 0.1f){ //상단 테두리
					PBEngine.ballx = 0.1f;
					sx = 0;
					vx = 0;
				}
				else{
					if(obstacleN()){
						sx = 0;
						vx = 0;
					}else{
						sx = vx + (0.5f)*PBGame.accY*(0.016f)*(0.015f);
						vx = vx + PBGame.accY*(0.016f)*(0.015f);
						PBEngine.ballx = PBEngine.ballx + sx;						
					}
				}
				oriX = 1;
			}else if(-9.8<=PBGame.accY && PBGame.accY<-0.1 && oriX == 2 ){
				sx = 0;
				vx = 0;
				oriX = 1;
			}else if(0.1<PBGame.accY && PBGame.accY<=9.8 && oriX != 1){
				if(PBEngine.ballx > 13.15f){ //하단 테두리
					PBEngine.ballx = 13.15f;
					sx = 0;
					vx = 0;
				}
				else{
					if(obstacleS()){
						sx = 0;
						vx = 0;
					}else{
						sx = vx + (0.5f)*PBGame.accY*(0.016f)*(0.015f);
						vx = vx + PBGame.accY*(0.016f)*(0.015f);
						PBEngine.ballx = PBEngine.ballx + sx;						
					}
				}
				oriX = 2;
			}else if(0.1<PBGame.accY && PBGame.accY<=9.8 && oriX == 1){
				sx = 0;
				vx = 0;
				oriX = 2;
			}			
			else{
				sx = 0;
				vx = 0;
				oriX = 0;
			}
		}
		
		private void instant(){
			int ran = 1 + (int)(Math.random() * 5);
			switch(ran){
				case 1 :
					PBEngine.ballx = 0.3f;
					PBEngine.bally = 0.3f;
					break;
				case 2 :
					PBEngine.ballx = 3.0f;
					PBEngine.bally = 6.7f;
					break;
				case 3 :
					PBEngine.ballx = 7.0f;
					PBEngine.bally = 5.4f;
					break;
				case 4 :
					PBEngine.ballx = 12.7f;
					PBEngine.bally = 6.7f;
					break;
				case 5 :
					PBEngine.ballx = 8.4f;
					PBEngine.bally = 0.2f;
					break;
			}
		}
		
		private void ball(GL10 gl){
			gl.glMatrixMode(GL10.GL_MODELVIEW);
			gl.glLoadIdentity();
			gl.glPushMatrix();
						
			acc();//가속도 적용
			if(inhole){
				instant();
				inhole = false;
			}
			CirBall.trans(PBEngine.ballx+0.475f, PBEngine.bally+0.475f);//공의 경계도형을 공의 움직임에 맞춰 이동
		   			
			gl.glScalef(0.078f * 0.9f, 0.138f * 0.9f, 0.1f * 0.9f);
			gl.glTranslatef(PBEngine.ballx, PBEngine.bally, 2f);
			gl.glMatrixMode(GL10.GL_TEXTURE);
			gl.glLoadIdentity();			
			ball.draw(gl);			
			gl.glPopMatrix();
			gl.glLoadIdentity();
		}
		
		private void background(GL10 gl){
			gl.glMatrixMode(GL10.GL_MODELVIEW);
			gl.glLoadIdentity();			
			gl.glPushMatrix();
			gl.glScalef(1f, 1f, 1f);
			gl.glTranslatef(0f, 0f, 0f);			
			gl.glMatrixMode(GL10.GL_TEXTURE);
			gl.glLoadIdentity();			
			background.draw(gl);
			gl.glPopMatrix();
			gl.glLoadIdentity();			
		}
		
		private void coin(GL10 gl){			
			for(int i=0; i < 7; i++){
				if(PBEngine.drawcoin[i] == 1){
					gl.glMatrixMode(GL10.GL_MODELVIEW);
					gl.glLoadIdentity();
					gl.glPushMatrix();
					gl.glScalef(0.078f * 0.9f, 0.138f * 0.9f, 0.1f * 0.9f);
					gl.glTranslatef(vec[i].x, vec[i].y, 2f);
					
					gl.glMatrixMode(GL10.GL_TEXTURE);
					gl.glLoadIdentity();
					
					coin[i].draw(gl);			
					gl.glPopMatrix();
					gl.glLoadIdentity();
				}
			}
		}
		
		private void clock(GL10 gl){
			gl.glMatrixMode(GL10.GL_MODELVIEW);
			gl.glLoadIdentity();
			gl.glPushMatrix();		   			
			gl.glScalef(0.078f * 0.9f, 0.138f * 0.9f, 0.1f * 0.9f);
			gl.glTranslatef(clockVec.x, clockVec.y, 2f);
			gl.glMatrixMode(GL10.GL_TEXTURE);
			gl.glLoadIdentity();			
			clock.draw(gl);			
			gl.glPopMatrix();
			gl.glLoadIdentity();
		}
		
		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height) {
			gl.glViewport(0, 0, width, height);
			float wf = (float) width / (float) 1280;
			float hf = (float) height / (float) 720;			
			gl.glMatrixMode(GL10.GL_PROJECTION);
			gl.glLoadIdentity();
			gl.glOrthof(0f, 1f * wf, 0f, 1f * hf, -1f, 1f); //직교 2D 형태
		}

		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
			gl.glEnable(GL10.GL_TEXTURE_2D);
			gl.glClearDepthf(1.0f);
			gl.glEnable(GL10.GL_DEPTH_TEST);
			gl.glDepthFunc(GL10.GL_LEQUAL);		
			
		    background.loadTexture(gl, PBEngine.BACKGROUND_LAYER_TWO, PBEngine.context);		
		    ball.loadTexture(gl, PBEngine.PLAYER_BALL, PBEngine.context);
		    for(int i=0; i<7; i++){
		    	coin[i].loadTexture(gl, PBEngine.PLAYER_COIN, PBEngine.context);  
		    }
		    clock.loadTexture(gl, PBEngine.PLAYER_CLOCK, PBEngine.context);
		}
		
}